from tkinter import messagebox
import tkinter as tk
from tkinter import ttk
import os
import logging
from data_processor import ProcessData
from config import AppConfig
import pandas as pd
from simple_multibeam_processor import SimpleMultibeamProcessor

logger = logging.getLogger(__name__)

class MainController:
    def __init__(self, config: AppConfig, processor: ProcessData):
        self.config = config
        self.processor = processor
        self.combo_box = None
        # 添加一个TimeConverter类的引用
        self.time_converter = None
        if hasattr(self.config, 'time_converter'):
            self.time_converter = self.config.time_converter
    
    def set_combo_box(self, combo_box: 'QComboBox') -> None:
        """设置下拉框引用"""
        self.combo_box = combo_box
        
    def select_section(self, index: int) -> None:
        """处理断面选择事件（优化版）
        参数:
            index: 当前选中的断面索引
        """
        if 0 <= index < len(self.config.notemenu):
            self.config.dmnum = index
            logger.debug(f"选择断面: {self.config.dmnum}")
            # self.operation()
        
    def dminc(self) -> None:
        """切换到下一个断面（安全版）"""
        if not self.config.notemenu:
            messagebox.showwarning('警告', '请先加载数据')
            return
            
        max_index = len(self.config.notemenu) - 1
        if self.config.dmnum < max_index:
            self.config.dmnum += 1
            self.combo_box.setCurrentIndex(self.config.dmnum)  # 改为PyQt的方法
            logger.info(f"下一个断面: {self.config.dmnum}")
            # self.operation()
        else:
            messagebox.showwarning('警告', '已在最后一条断面')
            
    def dmdec(self) -> None:
        """切换到上一个断面（安全版）"""
        if not self.config.notemenu:
            messagebox.showwarning('警告', '请先加载数据')
            return
            
        if self.config.dmnum > 0:
            self.config.dmnum -= 1
            self.combo_box.setCurrentIndex(self.config.dmnum)  # 改为PyQt的方法
            logger.info(f"上一个断面: {self.config.dmnum}")
            # self.operation()
        else:
            messagebox.showwarning('警告', '已在第一条断面')
            
    
    def ytfxbj(self) -> None:
        """切换原始绘图显示（安全版）"""
        # 确保状态数组足够长
        if len(self.config.ytfx) <= self.config.dmnum:
            self.config.ytfx.extend([0] * (self.config.dmnum - len(self.config.ytfx) + 1))
        
        # 切换状态
        new_state = not bool(self.config.ytfx[self.config.dmnum])
        self.config.ytfx[self.config.dmnum] = int(new_state)
        self.config.range_control = 0
        
        state_str = "显示" if new_state else "隐藏"
        logger.info(f"原始绘图 {state_str} (断面{self.config.dmnum})")
        
        # self.process_date()
        # self.operation()
        
    def operation(self) -> None:
        """主操作逻辑"""
        # 实现原有逻辑
        pass
        
    def process_date(self) -> None:
        try: 
            self.processor.process_file(self.config.notemenu[self.config.dmnum])
            # print("数据处理完成ZZFIX为",self.config.ZZFIX[self.config.dmnum])
        except Exception as e:
            logger.error(f"数据处理失败: {str(e)}", exc_info=True)
            messagebox.showerror('操作错误', str(e))
    
    def export_zzfix(self):
        """按dy0格式输出config.ZZFIX点（实况输出）"""
        try:
            # 确保配置中有必要的数据
            if not hasattr(self.config, 'line_numbers') or not self.config.line_numbers:
                raise ValueError("没有找到line_numbers数据")
                
           
            
            # 获取测量日期
            measure_date = self.config.line_numbers[0][0][:2] + self.config.line_numbers[0][0][3:5]  
            
            # 创建目标路径
            dy0_path = os.path.join(os.path.dirname(os.path.dirname(self.config.notemenu[0])), 'dy0')
            
            # 确保目标文件夹存在
            if not os.path.exists(dy0_path):
                os.makedirs(dy0_path)
                
            # 写入文件路径
            output_file = os.path.join(dy0_path, f'{self.config.ys_ss}{measure_date}.dy0')
            
            # 写入文件开头信息
            with open(output_file, 'w') as file:
                file.write(f'- - -  {self.config.line_numbers[0][0]}  - - - - -\n')
                file.write(f'{measure_date}.DY0\n\n')
            
            # 写入各断面信息
            n = 1
            with open(output_file, 'a', encoding='utf-8') as file:
                for i in range(len(self.config.ZZFIX)):
                    try:
                        dm_num = i
                        dm_name = os.path.splitext(os.path.basename(self.config.notemenu[dm_num]))[0]  
                        
                        # 处理用于输出的dataframe
                        if self.config.ys_ss == 'ss':
                            export_zzfix = self.config.ZZFIX[dm_num]
                        else:
                            export_zzfix = self.config.ys_ZZFIX[dm_num]
                        
                        # 处理export_zzfix至满足输出要求
                        export_zzfix['序号'] = export_zzfix['序号'].astype(int)
                        
                        # 使用TimeConverter将秒转换为时间
                        if self.time_converter and hasattr(self.time_converter, 'seconds_to_time'):
                            export_zzfix['24time'] = export_zzfix['时间'].astype(int).apply(self.time_converter.seconds_to_time)
                        else:
                            # 如果没有TimeConverter，使用简单的时间格式化
                            export_zzfix['24time'] = export_zzfix['时间'].astype(int).apply(lambda x: f"{x//3600:02d}:{(x%3600)//60:02d}:{x%60:02d}")
                        
                        export_zzfix['索引'] = export_zzfix.index + 1
                        export_zzfix['凑格式'] = '4-4'
                        export_zzfix['水深'] = -export_zzfix['水深']
                        export_zzfix = export_zzfix.fillna('')
                        
                        # 创建操作列
                        export_zzfix['操作'] = 0
                        if (hasattr(self.config, 'dfADD') and dm_num < len(self.config.dfADD) and not self.config.dfADD[dm_num].empty) or \
                           (hasattr(self.config, 'dfCHA') and dm_num < len(self.config.dfCHA) and not self.config.dfCHA[dm_num].empty):
                            if hasattr(self.config, 'dfADD') and dm_num < len(self.config.dfADD) and '时间' in self.config.dfADD[dm_num].columns:
                                export_zzfix.loc[export_zzfix['时间'].isin(self.config.dfADD[dm_num]['时间']), '操作'] += 1
                            if hasattr(self.config, 'dfCHA') and dm_num < len(self.config.dfCHA) and '时间' in self.config.dfCHA[dm_num].columns:
                                export_zzfix.loc[export_zzfix['时间'].isin(self.config.dfCHA[dm_num]['时间']), '操作'] += 2
                        
                        # 选择需要的列
                        export_zzfix = export_zzfix[['索引', '序号', '凑格式', '24time', 'E', 'N', '水深', '时间','操作']]
                        export_zzfix = export_zzfix.fillna('')
                        
                        # 写入断面信息
                        file.write(f'{dm_name}\n\n')
                        
                        # 写入断面线起止点
                        if self.config.line_numbers[dm_num][1] > self.config.line_numbers[dm_num][3]:
                            file.write(f'{self.config.line_numbers[dm_num][1]}' + '    ' + f'{self.config.line_numbers[dm_num][2]}\n')
                            file.write(f'{self.config.line_numbers[dm_num][3]}' + '    ' + f'{self.config.line_numbers[dm_num][4]}\n')
                        else:
                            file.write(f'{self.config.line_numbers[dm_num][3]}' + '    ' + f'{self.config.line_numbers[dm_num][4]}\n')
                            file.write(f'{self.config.line_numbers[dm_num][1]}' + '    ' + f'{self.config.line_numbers[dm_num][2]}\n')
                        file.write('\n')
                        
                        # 写入数据行 - 修改为与my_file copy.py相同的格式
                        for _, row in export_zzfix.iterrows():
                            file.write('{:>3}{:>5}{:>7}{:>12}{:>12.2f}{:>13.2f}{:>7.2f}{:>7}{:>6}\n'.format(
                                *row.iloc[:7], int(row.iloc[7]), *row.iloc[8:]))
                        
                        # 写入断面结束句 - 修改为与my_file copy.py相同的格式
                        file.write(f'- - - - - -第{n}线结束 - - - - - - - - - - - - - - - - - - - - -\n\n')
                        n = n + 1
                    except Exception as e:
                        logger.error(f"处理断面{n-1}时出错: {str(e)}")
                        continue
            
            # 添加成功提示
            if hasattr(self.config, 'label3'):
                self.config.label3.config(text=f"{dy0_path}\\{self.config.ys_ss}{measure_date}.dy0输出成功")
            
            logger.info(f"输出成功: {output_file}")
            return output_file
        except Exception as e:
            logger.error(f"导出失败: {str(e)}")
            if hasattr(self.config, 'label3'):
                self.config.label3.config(text=f"导出失败: {str(e)}")
            raise
    
    def ys_export_zzfix(self):
        """按dy0格式输出原始config.ZZFIX点（原始输出）"""
        try:
            # 设置输出模式为原始输出
            self.config.ys_ss = 'ys'
            # 调用export_zzfix方法
            output_file = self.export_zzfix()
            # 恢复为实况输出模式
            self.config.ys_ss = 'ss'
            return output_file
        except Exception as e:
            # 确保无论如何都恢复为实况输出模式
            self.config.ys_ss = 'ss'
            logger.error(f"原始导出失败: {str(e)}")
            raise

    def import_multibeam(self, file_path: str):
        """导入多波束数据文件
        
        Args:
            file_path: 多波束数据文件路径（支持TIFF格式）
        """
        try:
            # 创建SimpleMultibeamProcessor实例
            multibeam_processor = SimpleMultibeamProcessor(self.config)
            
            # 获取文件扩展名
            file_ext = os.path.splitext(file_path)[1].lower()
            
            # 判断文件类型并处理
            if file_ext in ['.tif', '.tiff']:
                # 直接调用多波束处理模块读取文件函数
                success = multibeam_processor.load_tiff_file(file_path)
                if success:
                    logger.info(f"成功导入多波束TIFF文件: {file_path}")
                    return True
                else:
                    raise Exception(f"加载TIFF文件失败: {file_path}")
            else:
                raise Exception(f"不支持的文件格式: {file_ext}")
        except Exception as e:
            logger.error(f"导入多波束数据失败: {str(e)}")
            raise

